package com.lovo.common.config;

import com.lovo.common.auth.*;

import jakarta.servlet.Filter;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import  org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguation {
//    @Autowired
//    private SessionRealm sessionRealm;
    @Autowired
    private JWTRealm jwtRealm;
    @Autowired
    private JWTDefaultSubjectFactory subjectFactory;
    /**
     * 配置Shiro核心 安全管理器 SecurityManager
     * SecurityManager安全管理器：所有与安全有关的操作都会与SecurityManager交互；且它管理着所有Subject；负责与后边介绍的其他组件进行交互。（类似于SpringMVC中的DispatcherServlet控制器）
     */
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        //将自定义的realm交给SecurityManager管理
//        securityManager.setRealm(sessionRealm);

        // 支持JWT
        securityManager.setRealm(jwtRealm);
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
// 不需要将 Shiro Session 中的东西存到任何地方（包括 Http Session 中）
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
//禁止Subject的getSession方法
        securityManager.setSubjectFactory(subjectFactory);
        return securityManager;
    }

    /**
     * 配置Shiro的Web过滤器，拦截浏览器请求并交给SecurityManager处理
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean webFilter(SecurityManager securityManager){

        // 支持Restful的方式
        ShiroFilterFactoryBean shiroFilterFactoryBean = new RestShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
        filters.put("perms", new RestAuthorizationFilter());
        filters.put("authc", new ShiroFormAuthenticationFilter());
//        Map filterChainMap = authorityService.loadFilterChainDefinitionMap();
        // 不支持Restful的方式
//        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//        shiroFilterFactoryBean.setSecurityManager(securityManager);
//        //配置拦截链 使用LinkedHashMap,因为LinkedHashMap是有序的，shiro会根据添加的顺序进行拦截
        // Map<K,V> K指的是拦截的url V值的是该url是否拦截
        Map<String,String> filterChainMap = new LinkedHashMap<String,String>(16);
//
//        List<Authority> authorityList = authorityService.list();
//        //authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问,先配置anon再配置authc。
//
        filterChainMap.put("/users/login","anon");
        filterChainMap.put("/swagger-ui/**","anon");
        filterChainMap.put("/v3/api-docs/**","anon");
//        authorityList.forEach(item -> filterChainMap.put(item.getPath(),"perms["+item.getName()+"]"));
//        filterChainMap.put("/**", "authc");
        filterChainMap.put("/**", "anon");
        //设置拦截请求后跳转的URL.
//        shiroFilterFactoryBean.setUnauthorizedUrl("/authorizationError");
//        shiroFilterFactoryBean.setLoginUrl("/authenticationError");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        return shiroFilterFactoryBean;
    }

}
